package cn.mrcode.wxsdk.web.common.ticket.lifeCycle.distributed;


import cn.mrcode.wxsdk.core.dialogue.common.PublicAccount;
import cn.mrcode.wxsdk.web.common.ticket.lifeCycle.ITicketService;
import cn.mrcode.wxsdk.web.common.ticket.lifeCycle.distributed.strategy.master.TicketDistributedTaskMaster;
import cn.mrcode.wxsdk.web.common.ticket.lifeCycle.distributed.strategy.master_old.ZkTicket;
import cn.mrcode.wxsdk.web.protocol.base.JsApiTicketInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author zhuqiang
 * @version V1.0
 * @Description: 分布式 ticket 生命周期维护
 * @date 2015/9/28 11:27
 */
public class TicketDistributedService implements ITicketService {
    private static Logger log = LoggerFactory.getLogger(TicketDistributedService.class);

    private static final ConcurrentHashMap<String, JsApiTicketInfo> ticketMap = new ConcurrentHashMap<String, JsApiTicketInfo>();
    private static TicketDistributedService instance;
    private static ReentrantLock lock = new ReentrantLock();

    @Deprecated
    public static TicketDistributedService getInstance(int sessionTimeout, String zkServiceList, String rootPath, HashMap<String, PublicAccount> accountMap) {
        lock.lock();
        try {
            if (instance == null) {
                instance = new TicketDistributedService();
                ZkTicket zt = new ZkTicket(sessionTimeout, zkServiceList, rootPath, ticketMap, accountMap);
                zt.init();
//                log.debug("分布式jssdk ticket已被初始化ZkTicket");
            }
        } finally {
            lock.unlock();
        }
        return instance;
    }

    /**
     * 获取curator实现的 服务
     * @param sessionTimeout
     * @param zkServiceList
     * @param publicAccountMap
     * @return
     */
    public static ITicketService getInstance(int sessionTimeout, String zkServiceList, HashMap<String, PublicAccount> publicAccountMap) {
        lock.lock();
        try {
            if (instance == null) {
                instance = new TicketDistributedService();
                TicketDistributedTaskMaster master = new TicketDistributedTaskMaster(sessionTimeout,zkServiceList,publicAccountMap,ticketMap);
                try {
                    master.init();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } finally {
            lock.unlock();
        }
        return instance;
    }

    @Override
    public String getJsApiTicke(String appid, String secret) throws Exception{
        JsApiTicketInfo ati = ticketMap.get(appid);
        int i = 0;
        while (ati == null) {
            if (i == 3) {
                String errMsg = "获取ticket失败,本地没有可用ticket";
                log.error(errMsg);
                throw new Exception(errMsg);
            }
            TimeUnit.MILLISECONDS.sleep(200); //为空则休眠200毫秒再获取
            ati = ticketMap.get(appid);
            i++;
        }
        return ati.getJsapi_ticket();
    }
}
